﻿using System;
using System.Linq;
using System.Data.Linq;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Collections.Generic;
using ConsolidationTool.Common;

namespace ConsolidationTool.WebParts.Layouts.CReport
{
    public partial class IntercoReconciliationReport : FSReportBase
    {
        public class IntercoReconciliationEntity
        {
            private SPListItem item;
            public IntercoReconciliationEntity() { }
            public IntercoReconciliationEntity(SPListItem sPListItem, string Seller, string Buyer)
            {
                // TODO: Complete member initialization
                this.item = sPListItem;

                AccountCode = item["LM_AccountCode"] + "";
                AccountCode = AccountCode.Length > 10 ? AccountCode.Substring(0, 10) : AccountCode;
                string _Identity = AccountCode == "PI01030000" ? "PI01020000" : AccountCode;//兼容
                _Identity = AccountCode == "SI01050201" ? "SI01050201_x0020_" : _Identity;

                if (!string.IsNullOrEmpty(Buyer))
                {
                    this.Buyer = Buyer;
                    this.Seller = item["Company Name"] + "";

                    Buyer_Qty = item["CM_QTY_" + _Identity] + "";
                    Buyer_IC = item["CM_IC_" + _Identity] + "";
                    Buyer_IA = item["CM_IA_" + _Identity] + "";
                }
                else
                {
                    this.Seller = Seller;
                    this.Buyer = item["Company Name"] + "";

                    Seller_Qty = item["CM_QTY_" + _Identity] + "";
                    Seller_IC = item["CM_IC_" + _Identity] + "";
                    Seller_IA = item["CM_IA_" + _Identity] + "";
                }
            }


            public string AccountCode { get; set; }
            public string Description { get; set; }
            public string Seller { get; set; }
            public string Buyer { get; set; }
            public string Seller_Qty { get; set; }
            public string Seller_IC { get; set; }
            public string Seller_IA { get; set; }
            public string Buyer_Qty { get; set; }
            public string Buyer_IC { get; set; }
            public string Buyer_IA { get; set; }

            public int Index { get; set; }
        }

        public override ControlTemplates.CommonEntitySelector TopSelector
        {
            get
            {
                return commonEntitySelector as ControlTemplates.CommonEntitySelector;
            }
        }

        public override void GenerateReport_Click(object sender, EventArgs e)
        {
            IntercoMapping.Add("SI01010201", "PI01010000");
            IntercoMapping.Add("SI01030201", "PI01020000");
            IntercoMapping.Add("SI01040101", "PI01030000");
            IntercoMapping.Add("SI01050201", "PI01040000");
            IntercoMapping.Add("SI01060201", "PI01050000");

            IntercoMapping.Add("SI03010201", "PI03010000");
            IntercoMapping.Add("SI03030201", "PI03020000");
            IntercoMapping.Add("SI03040101", "PI03030000");
            IntercoMapping.Add("SI03050201", "PI03040000");
            IntercoMapping.Add("SI03060201", "PI03050000");

            TitleMapping.Add("SI01010201", "Prod Sales - Internal Asia");
            TitleMapping.Add("PI01010000", "Prod Purchased - Internal Asia");
            TitleMapping.Add("SI01030201", "Service Sales - Internal Asia");
            TitleMapping.Add("PI01020000", "Service Purchased - Internal Asia");
            TitleMapping.Add("SI01040101", "Commission sales - Internal Asia");
            TitleMapping.Add("PI01030000", "Commission Purchased - Internal Asia");
            TitleMapping.Add("SI01050201", "Others sales - Internal Asia");
            TitleMapping.Add("PI01040000", "Others Purchased - Internal Asia");
            TitleMapping.Add("SI01060201", "Interest sales - Internal Asia");
            TitleMapping.Add("PI01050000", "Interest Purchased - Internal Asia");

            TitleMapping.Add("SI03010201", "Prod Sales - Internal Asia");
            TitleMapping.Add("PI03010000", "Prod Purchased - Internal Asia");
            TitleMapping.Add("SI03030201", "Service Sales - Internal Asia");
            TitleMapping.Add("PI03020000", "Service Purchased - Internal Asia");
            TitleMapping.Add("SI03040101", "Commission sales - Internal Asia");
            TitleMapping.Add("PI03030000", "Commission Purchased - Internal Asia");
            TitleMapping.Add("SI03050201", "Others sales - Internal Asia");
            TitleMapping.Add("PI03040000", "Others Purchased - Internal Asia");
            TitleMapping.Add("SI03060201", "Interest sales - Internal Asia");
            TitleMapping.Add("PI03050000", "Interest Purchased - Internal Asia");

            IndexMapping.Add("SI01010201", 1000);
            IndexMapping.Add("PI01010000", 2000);
            IndexMapping.Add("SI01030201", 3000);
            IndexMapping.Add("PI01020000", 4000);
            IndexMapping.Add("SI01040101", 5000);
            IndexMapping.Add("PI01030000", 6000);
            IndexMapping.Add("SI01050201", 7000);
            IndexMapping.Add("PI01040000", 8000);
            IndexMapping.Add("SI01060201", 9000);
            IndexMapping.Add("PI01050000", 10000);

            IndexMapping.Add("SI03010201", 1000);
            IndexMapping.Add("PI03010000", 2000);
            IndexMapping.Add("SI03030201", 3000);
            IndexMapping.Add("PI03020000", 4000);
            IndexMapping.Add("SI03040101", 5000);
            IndexMapping.Add("PI03030000", 6000);
            IndexMapping.Add("SI03050201", 7000);
            IndexMapping.Add("PI03040000", 8000);
            IndexMapping.Add("SI03060201", 9000);
            IndexMapping.Add("PI03050000", 10000);

            CreateEntityMapping();
            var allActualData = new List<IntercoReconciliationEntity>();
            var allBudgetData = new List<IntercoReconciliationEntity>();

            EntityMapping.ToList().ForEach(p =>
            {
                allActualData.AddRange(GetActualIntercoByEntity(p.Key, p.Value, CEntity.Year, CEntity.Month));

                allBudgetData.AddRange(GetBudgetIntercoByEntity(p.Key, p.Value, CEntity.Year, CEntity.Month));

                //    allData.Add(new IntercoReconciliationEntity());
            });

            allActualData = allActualData.OrderBy(p => p.Index / 1000).ToList();
            allBudgetData = allBudgetData.OrderBy(p => p.Index / 1000).ToList();

            //add empty row
            TitleMapping.Where(p=>p.Key.StartsWith("PI")).ToList().ForEach(t =>
            {
                int actualIndex = allActualData.FindLastIndex(p => p.AccountCode == t.Key);
                int budgetIndex = allBudgetData.FindLastIndex(p => p.AccountCode == t.Key);

                if (actualIndex != -1)
                    allActualData.Insert(actualIndex+1, new IntercoReconciliationEntity());
                if (budgetIndex != -1)
                    allBudgetData.Insert(budgetIndex+1, new IntercoReconciliationEntity());
            });


            gvActualIntercoReport.AutoGenerateColumns = true;
            gvActualIntercoReport.DataSource = allActualData.ToDataTable();
            gvActualIntercoReport.DataBind();

            gvBudgetIntercoReport.AutoGenerateColumns = true;
            gvBudgetIntercoReport.DataSource = allBudgetData.ToDataTable();
            gvBudgetIntercoReport.DataBind();
        }

        private void CreateEntityMapping()
        {
            var web = SPContext.Current.Web;
            var list = web.Lists["Entity"];
            int itemCount = list.Items.Count;
            for (int i = 0; i < itemCount; i++)
            {
                var item = list.Items[i];
                EntityMapping.Add(item["Title"] + "", item["ConsolidationTool_CoCd"] + "");
                CoCdMapping.Add(item["ConsolidationTool_CoCd"] + "", item["Title"] + "");
            }

        } 

        public Dictionary<string, string> EntityMapping = new Dictionary<string, string>();
        public Dictionary<string, string> CoCdMapping = new Dictionary<string, string>();
        public Dictionary<string, string> IntercoMapping = new Dictionary<string, string>();
        public Dictionary<string, int> IndexMapping = new Dictionary<string, int>();
        public Dictionary<string, string> TitleMapping = new Dictionary<string, string>();

        public List<IntercoReconciliationEntity> GetBudgetIntercoByEntity(string entityname, string cocd, int year, int month)
        {
            var allSellersData = new List<IntercoReconciliationEntity>();
            //step 1 get sell data
            var web = SPContext.Current.Web;
            var query = new SPQuery()
            {
                Query = string.Format(@" <Where>
                                                              <And>
                                                                 <Eq>
                                                                    <FieldRef Name='CoCd' />
                                                                    <Value Type='Text'>{0}</Value>
                                                                 </Eq>
                                                                 <Eq>
                                                                    <FieldRef Name='Year' />
                                                                    <Value Type='Integer'>{1}</Value>
                                                                 </Eq>
                                                              </And>
                                                           </Where>", cocd, year)
            };
            var subPID = SPContext.Current.Web.Lists["Budget_PI"];
            var subSID = SPContext.Current.Web.Lists["Budget_SID"];

            var items = subSID.GetItems(query);
            int itemCount = items.Count;
            if (itemCount > 0)
            {
                string BillData = items[0]["BillData"] + "";
                var itemEntitys = BusinessService.RefJsonData<fsentity>(BillData);
                itemEntitys.Where(p => p.subrow != null).ToList().ForEach(p =>
                {
                    int i = 1;
                    p.subrow.ForEach(s =>
                    {
                        var newIRE = new IntercoReconciliationEntity();
                        newIRE.AccountCode = p.accountcode;
                        newIRE.Description = TitleMapping[p.accountcode];
                        newIRE.Seller = entityname;
                        newIRE.Buyer = CoCdMapping[s.entity];
                        newIRE.Seller_IA = s.TryGetValue(CEntity.EngMonth + "_IA") + "";
                        newIRE.Seller_IC = s.TryGetValue(CEntity.EngMonth + "_IC") + "";
                        newIRE.Seller_Qty = s.TryGetValue(CEntity.EngMonth + "_Qty") + "";

                        newIRE.Index = (IndexMapping[newIRE.AccountCode] + i) * 1000;
                        allSellersData.Add(newIRE);
                        i++;
                    });
                });
            }
            //step 2 get purchase data
            var allPurchaseData = new List<IntercoReconciliationEntity>();
            query = new SPQuery()
            {
                Query = string.Format(@" <Where>
                                                              <Eq>
                                                                 <FieldRef Name='Year' />
                                                                 <Value Type='Integer'>{0}</Value>
                                                              </Eq>
                                                           </Where>", year)
            };
            items = subPID.GetItems(query);
            itemCount = items.Count;
            for (int i = 0; i < itemCount; i++)
            {
                string BillData = items[i]["BillData"] + "";
                var itemEntitys = BusinessService.RefJsonData<fsentity>(BillData);
                itemEntitys.Where(p => p.subrow != null).ToList().ForEach(p =>
                {

                    p.subrow.ForEach(s =>
                    {
                        var newIRE = new IntercoReconciliationEntity();
                        newIRE.AccountCode = p.accountcode;
                        newIRE.Description = TitleMapping[p.accountcode];
                        newIRE.Seller = entityname;
                        newIRE.Buyer = items[i]["Company Name"] + "";
                        newIRE.Buyer_IA = s.TryGetValue(CEntity.EngMonth + "_IA") + "";
                        newIRE.Buyer_IC = s.TryGetValue(CEntity.EngMonth + "_IC") + "";
                        newIRE.Buyer_Qty = s.TryGetValue(CEntity.EngMonth + "_Qty") + "";

                        allPurchaseData.Add(newIRE);
                    });
                });
            }
            //step 3 更新卖方数据
            var upgredeBuyerData = new List<IntercoReconciliationEntity>();
            int round = 1;
            allSellersData.ForEach(s =>
            {
                bool isEmptyRow = false;
                var seller = allPurchaseData.FirstOrDefault(p => p.Buyer == s.Buyer && p.AccountCode == IntercoMapping[s.AccountCode]);//根据卖方 通过买方code和标识 获取买方数据
                if (seller == null)
                {
                    seller = new IntercoReconciliationEntity() { AccountCode = IntercoMapping[s.AccountCode] };
                    isEmptyRow = true;
                }
                seller.Index = s.Index + round;
                upgredeBuyerData.Add(seller);
                if (!isEmptyRow)
                    allPurchaseData.Remove(seller);
                round++;
            });

            if (allPurchaseData.Count > 0)
            {
                allPurchaseData.ForEach(p => p.Description += " Undefined in seller interco");
                allSellersData.AddRange(allPurchaseData);
            }

            allSellersData.AddRange(upgredeBuyerData);
          //  allSellersData.ForEach(p => { p.Description = TitleMapping[p.AccountCode]; });

            return allSellersData.OrderBy(p => p.Index).ToList();

        }

        public List<IntercoReconciliationEntity> GetActualIntercoByEntity(string entityname, string cocd, int year, int month)
        {
            var allSellersData = new List<IntercoReconciliationEntity>();
            //step 1 get sell data
            var web = SPContext.Current.Web;
            var query = new SPQuery()
            {
                Query = string.Format(@" <Where>
                                          <And>
                                             <Eq>
                                                <FieldRef Name='CoCd' />
                                                <Value Type='Text'>{0}</Value>
                                             </Eq>
                                             <And>
                                                <Eq>
                                                   <FieldRef Name='Year' />
                                                   <Value Type='Integer'>{1}</Value>
                                                </Eq>
                                                <Eq>
                                                   <FieldRef Name='Month' />
                                                   <Value Type='Integer'>{2}</Value>
                                                </Eq>
                                             </And>
                                          </And>
                                       </Where>", cocd, year, month)
            };
            var subPID = SPContext.Current.Web.Lists["Sub Purchase Interco Declaration"];
            var subSID = SPContext.Current.Web.Lists["Sub Sales Interco Declaration"];

            var items = subSID.GetItems(query);
            int itemCount = items.Count;
            for (int i = 0; i < itemCount; i++)
            {
                var newIRE = new IntercoReconciliationEntity(items[i], entityname, "");

                newIRE.Index = (IndexMapping[newIRE.AccountCode] + i) * 1000;
                allSellersData.Add(newIRE);
            }

            //step 2 get purchase data
            var allPurchaseData = new List<IntercoReconciliationEntity>();
            query = new SPQuery()
            {
                Query = string.Format(@" <Where>
                                          <And>
                                             <Eq>
                                                <FieldRef Name='CoName' />
                                                <Value Type='Text'>{0}</Value>
                                             </Eq>
                                             <And>
                                                <Eq>
                                                   <FieldRef Name='Year' />
                                                   <Value Type='Integer'>{1}</Value>
                                                </Eq>
                                                <Eq>
                                                   <FieldRef Name='Month' />
                                                   <Value Type='Integer'>{2}</Value>
                                                </Eq>
                                             </And>
                                          </And>
                                       </Where>", entityname, year, month)
            };
            items = subPID.GetItems(query);
            itemCount = items.Count;
            for (int i = 0; i < itemCount; i++)
            {
                var newIRE = new IntercoReconciliationEntity(items[i], "", CoCdMapping[items[i]["CoCd"] + ""]);
                // newIRE.Index = (i+1) * 100;
                allPurchaseData.Add(newIRE);
            }

            //step 3 更新卖方数据
            var upgredePurchaseData = new List<IntercoReconciliationEntity>();
            int round = 1;
            allSellersData.ForEach(s =>
            {
                bool isEmptyRow = false;
                var purchase = allPurchaseData.FirstOrDefault(p => p.Buyer == s.Buyer && p.AccountCode == IntercoMapping[s.AccountCode]);//根据卖方 通过买方code和标识 获取买方数据
                if (purchase == null)
                {
                    purchase = new IntercoReconciliationEntity() { AccountCode = IntercoMapping[s.AccountCode] };
                    isEmptyRow = true;
                }

                purchase.Index = s.Index + round;
                upgredePurchaseData.Add(purchase);
                if (!isEmptyRow)
                    allPurchaseData.Remove(purchase);

                round++;
            });


            allSellersData.AddRange(upgredePurchaseData);
            allSellersData.ForEach(p => { p.Description = TitleMapping[p.AccountCode]; });
            if (allPurchaseData.Count > 0)
            {
                allPurchaseData.ForEach(p => p.Description = TitleMapping[p.AccountCode] + " Undefined in seller interco");
                allSellersData.AddRange(allPurchaseData);
            }
            return allSellersData.OrderBy(p => p.Index).ToList();
        }

    }
}
